/////////////////////////////////////////////////////////////////////////////
// Name:        ax_menu_folder.h
// Purpose:     Modal folder selection menu class
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_MENU_FOLDER_H_
#define _AX_MENU_FOLDER_H_

class AxFolderMenuItem;

/*
 * Includes
 */

#include "ax/ax_menu.h"
#include "ax/ax_menu_modal.h"
#include "ax/ax_activator.h"
#include "ax/ax_validator.h"
 
/*
 * Styles and types
 */

#define axFOLDER_MENU_STYLE_FILE_SELECTOR       0x0001
#define axFOLDER_MENU_STYLE_SHOW_HIDDEN_FILES   0x0002
#define axFOLDER_MENU_STYLE_NEW_FOLDER          0x0004

/**
    @class AxModalFolderMenu

    Shows a modal folder menu.

    @category{ax}

 */

class AxModalFolderMenu: public AxModalMenu
{
    DECLARE_CLASS( AxModalFolderMenu )

public:
// Constructors

    AxModalFolderMenu() { Init(); }

    AxModalFolderMenu(AxMenuController* controller, AxMenuItem* item,
        const wxString& menuLabel,
        const wxString& description,
        const wxString& defaultPath,
        int style = axFOLDER_MENU_STYLE_NEW_FOLDER,
        const wxString& filter = wxT("*"));
    
    ~AxModalFolderMenu() {}

    void SetPath(const wxString& path) { m_path = path; }
    wxString GetPath() const { return m_path; }

    AxMenu* CreateSubMenu(const wxString& folder, const wxString& folderName, const wxString& label, const wxString& description);

// Operations

    void Init();

    int GetStyle() const { return m_style; }
    void SetStyle(int style) { m_style = style; }

    bool IsFileSelector() const { return (m_style & axFOLDER_MENU_STYLE_FILE_SELECTOR) != 0; }
    bool ShowHiddenFiles() const { return (m_style & axFOLDER_MENU_STYLE_SHOW_HIDDEN_FILES) != 0; }

    // Set the filter, of the form "JPEG Files (*.jpg;*.jpeg)|*.jpg;*.jpeg"
    void SetFilter(const wxString& filter) { m_filter = filter; }
    const wxString& GetFilter() const { return m_filter; }

protected:

    wxString    m_path;
    int         m_style;
    wxString    m_filter;
};

/**
    @class AxFolderMenuActivator

    Handles activation of a folder or other command.

    @category{ax}

 */

class AxFolderMenuActivator: public AxActivator
{
public:

    typedef enum 
    {
        AxFolderCommandUnknown,
        AxFolderCommandFolder,
        AxFolderCommandFile,
        AxFolderCommandSelectThis,
        AxFolderCommandNewFolder,
        AxFolderCommandCancel,
            
    } AxFolderCommand;
    
    DECLARE_DYNAMIC_CLASS( AxFolderMenuActivator )

public:
// Constructors

    AxFolderMenuActivator() { Init(); }
    AxFolderMenuActivator(AxFolderCommand command, AxModalFolderMenu* menu, const wxString& folderPath = wxEmptyString, const wxString& folderName = wxEmptyString)
    { Init(); m_command = command; m_folderMenu = menu; m_folderPath = folderPath; m_folderName = folderName; }
    AxFolderMenuActivator(const AxFolderMenuActivator& activator) { Init(); Copy(activator); }

// Operations

    void Init() { m_folderMenu = NULL; }

    void Copy(const AxFolderMenuActivator& activator);

    virtual AxActivator* Clone() const { return new AxFolderMenuActivator(*this); }

    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

    AxModalFolderMenu* GetModalFolderMenu() const { return m_folderMenu; }
    void SetModalFolderMenu(AxModalFolderMenu* menu) { m_folderMenu = menu; }

    void SetFolderPath(const wxString& path) { m_folderPath = path; }
    const wxString& GetFolderPath() const { return m_folderPath; }

    void SetFolderName(const wxString& name) { m_folderName = name; }
    const wxString& GetFolderName() const { return m_folderName; }

    AxFolderCommand GetCommand() const { return m_command; }

protected:

    AxModalFolderMenu*  m_folderMenu;
    AxFolderCommand     m_command;
    wxString            m_folderPath; // full path
    wxString            m_folderName; // name only
};

/**
    @class AxFolderActivator

    A ready-made menu item activator which sets a string
    when the user chooses a folder.

    @category{ax}

 */

class AxFolderActivator: public AxAutoUpdateActivator
{
public:
    
    DECLARE_DYNAMIC_CLASS( AxFolderActivator )

public:
// Constructors

    AxFolderActivator() { Init(); }
    AxFolderActivator(const AxFolderActivator& activator) { Init(); Copy(activator); }
    AxFolderActivator(const wxString& itemLabelSpec,
                      const wxString& itemDescriptionSpec);

// Operations

    void Init() { }

    void Copy(const AxFolderActivator& activator);

    virtual AxActivator* Clone() const { return new AxFolderActivator(*this); }

    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

    /// Create menu label or description
    virtual wxString CreateString(const wxString& spec, bool WXUNUSED(isLabel));

    /// Find the child menu for the default folder.
    AxMenu* FindChildMenu(AxMenuController* controller, const wxString& defaultFolder, AxMenu* menu);

    AxFolderMenuItem* GetFolderMenuItem() const;

protected:

};

/**
    @class AxModalFileMenu

    @category{ax}

 */

class AxModalFileMenu: public AxModalFolderMenu
{
    DECLARE_CLASS( AxModalFileMenu )

public:
// Constructors

    AxModalFileMenu() { }

    AxModalFileMenu(AxMenuController* controller, AxMenuItem* item,
        const wxString& menuLabel,
        const wxString& description,
        const wxString& defaultPath,
        int style = axFOLDER_MENU_STYLE_FILE_SELECTOR,
        const wxString& filter = wxT("*"));
    
protected:

};

/**
    @class AxFolderMenuItem

    @category{ax}

 */

class AxFolderMenuItem: public AxMenuItem
{
    DECLARE_DYNAMIC_CLASS( AxFolderMenuItem )

public:
// Constructors

    AxFolderMenuItem(const AxFolderMenuItem& item) { Copy(item); }
    AxFolderMenuItem() {}
    AxFolderMenuItem(
        const wxString& label, const wxString& description,
        const wxString& id,
        const wxString& path,
        const wxString& filter = wxT("*"),
        int style = axFOLDER_MENU_STYLE_NEW_FOLDER);
    bool Create(
        const wxString& label, const wxString& description,
        const wxString& id,
        const wxString& path,
        const wxString& filter = wxT("*"),
        int style = axFOLDER_MENU_STYLE_NEW_FOLDER);

    void Copy(const AxFolderMenuItem& item);

    virtual AxMenuItem* Clone() const { return new AxFolderMenuItem(*this); }

    /// Set path
    void SetPath(const wxString& path);

    /// Get path
    const wxString& GetPath() const { return m_path; }

    void SetMenuLabel(const wxString& menuLabel) { m_menuLabel = menuLabel; }
    const wxString& GetMenuLabel() const { return m_menuLabel; }

    void SetMenuDescription(const wxString& menuDescription) { m_menuDescription = menuDescription; }
    const wxString& GetMenuDescription() const { return m_menuDescription; }

    void SetStyle(int style) { m_style = style; }
    int GetStyle() const { return m_style; }

    void SetFilter(const wxString& filter) { m_filter = filter; }
    const wxString& GetFilter() const { return m_filter; }

    wxString CreateString(const wxString& spec, bool isLabel);

protected:

    wxString    m_path;
    wxString    m_menuLabel;
    wxString    m_menuDescription;
    int         m_style; // folder/file selector style
    wxString    m_filter;
};

/**
    @class AxFileMenuItem

    @category{ax}

 */

class AxFileMenuItem: public AxFolderMenuItem
{
    DECLARE_DYNAMIC_CLASS( AxFileMenuItem )

public:
// Constructors

    AxFileMenuItem(const AxFileMenuItem& item) { Copy(item); }
    AxFileMenuItem() {}
    AxFileMenuItem(const wxString& label, const wxString& description,
        const wxString& id,
        const wxString path,
        const wxString& filter = wxT("*"),
        int style = 0);
    bool Create(const wxString& label, const wxString& description,
        const wxString& id,
        const wxString path,
        const wxString& filter = wxT("*"),
        int style = axFOLDER_MENU_STYLE_NEW_FOLDER);

    virtual AxMenuItem* Clone() const { return new AxFileMenuItem(*this); }
};

/**
    @class AxFolderValidator
 */

class AxFolderValidator: public AxValidator
{
    DECLARE_DYNAMIC_CLASS( AxFolderValidator )

public:
// Constructors

    AxFolderValidator(const AxFolderValidator& validator) { Init(); Copy(validator); }
    AxFolderValidator(wxString* ptr) { Init(); m_stringPtr = ptr; }
    AxFolderValidator() { Init(); }
    ~AxFolderValidator() {}

// Operations

    void Copy(const AxFolderValidator& validator)
    {
        AxValidator::Copy(validator);

        m_stringPtr = validator.m_stringPtr;
    }

    virtual AxValidator* Clone() const { return new AxFolderValidator(*this); }

    /// Override to pass a value from the UI to a data structure
    virtual bool TransferDataFromMenu();

    /// Override to pass a value from a data structure to the UI
    virtual bool TransferDataToMenu();

    /// Initialize variables
    void Init() { m_stringPtr = NULL; }

protected:
    wxString*   m_stringPtr;
};


#endif
    // _AX_MENU_FOLDER_H_
